package com.gugee.common.web.system.promise;

import com.gugee.common.web.util.AspectUtil;
import com.gugee.common.web.util.jwt.JwtUtil;
import com.gugee.common.web.system.promise.validate.Validate;
import com.gugee.common.web.system.promise.validate.ValidateFactory;
import com.gugee.common.web.system.user.model.User;
import com.gugee.common.web.system.user.repository.UserRepository;
import com.gugee.common.web.system.user.repository.UserRoleRepository;
import com.gugee.common.web.system.promise.repository.PermissionRepository;
import com.gugee.common.web.system.promise.validate.TimeLimit;
import com.xiguaji.boot.toolkit.HttpUtil;
import com.xiguaji.boot.toolkit.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;

import java.net.URLDecoder;
import java.util.Date;
import java.util.Map;

@Slf4j
public class ValidateAspect {

    @Autowired
    ValidateFactory validateFactory;

    @Autowired
    UserRepository userRepository;

    /*@Autowired
    MyTiktokService myTiktokService;*/

    @Autowired
    PermissionRepository permissionRepository;

    @Value("${jwt.head}")
    String authorized;

    @Autowired
    JwtUtil jwtUtil;

    @Autowired
    UserRoleRepository userRoleRepository;


    protected boolean requestLimitValidate(RequestLimit requestLimit,ProceedingJoinPoint proceedingJoinPoint, Validate validate){
        validate.setPermissionId(requestLimit);
        if(requestLimit.validateType().getValue() == Limit.PROPERTY_LIMIT.getValue()) {
            return validate.validate(getRoleId(),getParamsValue(requestLimit,proceedingJoinPoint));
        }else if( requestLimit.validateType().getValue() == Limit.VIEW_DATA_LIMIT.getValue()){
            val propertys = requestLimit.property().split(",|，");
            int value = 0;
            for (String property : propertys) {
                if(value == 0){
                    value = Integer.parseInt(getParamsValue(requestLimit,proceedingJoinPoint,property));
                }else{
                    value = value*Integer.parseInt(getParamsValue(requestLimit,proceedingJoinPoint,property));
                }
            }
            return validate.validate(getRoleId(),value);
        }else if( requestLimit.validateType().getValue() == Limit.DAY_LIMIT.getValue()){
            String value = getParamsValue(requestLimit,proceedingJoinPoint);
            return validate.validate(getRoleId(),getUser().getId(), TimeLimit.TimeType.DAY, value);
        }else if( requestLimit.validateType().getValue() == Limit.ADD_SUB_USER.getValue()){
            int count = userRepository.countByParentId(getUser().getId());
            return validate.validate(getRoleId(),count);
        }else if( requestLimit.validateType().getValue() == Limit.ADD_MY_TIKTOK_LIMIT.getValue()){
            /*int count = myTiktokService.getTBloggerData(getUser().getId()).size();
            return validate.validate(getRoleId(),count);*/
        }else if( requestLimit.validateType().getValue() == Limit.MONTH_LIMIT.getValue()){
            return validate.validate(getRoleId(),getUser().getId(), TimeLimit.TimeType.MONTH);
        }else if(requestLimit.validateType().getValue() == Limit.REPORT_LIMIT.getValue()){
            String value = getParamsValue(requestLimit,proceedingJoinPoint);
            return validate.validate(getRoleId(),getUser().getId(),value);
        }
        return false;
    }


    private String getParamsValue(RequestLimit requestLimit,ProceedingJoinPoint proceedingJoinPoint) {
        return getParamsValue(requestLimit,proceedingJoinPoint,requestLimit.property());
    }

    private String getParamsValue(RequestLimit requestLimit,ProceedingJoinPoint proceedingJoinPoint,String property){
        String value = "";
        try{
            if(requestLimit.paramType() == ParamsType.PARAMS){
                Map<String, String[]> parameterMap = HttpUtil.getRequest().getParameterMap();
                value = parameterMap.get(property).toString();

            }else if(requestLimit.paramType() == ParamsType.JSON){
                Map t = JsonUtil.jsonParse(Map.class, URLDecoder.decode(proceedingJoinPoint.getArgs()[0].toString(),"UTF-8"));

                if(null == t){
                    t = JsonUtil.jsonParse(Map.class, URLDecoder.decode(proceedingJoinPoint.getArgs()[1].toString(),"UTF-8"));
                }
                value = t.get(property).toString();
            }else if(requestLimit.paramType() == ParamsType.URL){
                val mappingAnnotation = AspectUtil.INSTANCE.getMethod(proceedingJoinPoint).getAnnotation(RequestMapping.class);
                // 截取不存在占位符的Mapping
                String mappingUrl = mappingAnnotation.value()[0].substring(0,mappingAnnotation.value()[0].indexOf("{"));
                // 获取占位符中的URL
                String url = HttpUtil.getRequestUrl().substring(HttpUtil.getRequestUrl().indexOf(mappingUrl));
                String [] params = url.split("/");
                String [] mappings = mappingAnnotation.value()[0].substring(
                        mappingAnnotation.value()[0].indexOf(mappingUrl)
                ).split("/");
                for (int i = 0; i < mappings.length; i++) {
                    if(mappings[i].contains("{")&&mappings[i].contains(property)){
                        value = params[i];
                    }
                }
            }
        }catch (Exception e){
            log.error("requestLimit error:",e);
        }
        return value;
    }

    private long getRoleId(){
        long roleId = 1;
        User user = getUser();
        val userRoleOptional = userRoleRepository.findTop1ByUserIdAndExpireTimeGreaterThanEqualOrderByRoleIdDesc(user.getParentId() == 0 ?user.getId():user.getParentId(), new Date());

        if(userRoleOptional.isPresent()){
            roleId = userRoleOptional.get().getRoleId();
        }
        return roleId;
    }

    private User getUser(){
        String token = HttpUtil.getCookie(authorized);
        return JsonUtil.jsonParse(User.class,JsonUtil.parseJson(jwtUtil.getJwtUser(token).getUser()));
    }
}
